package com.ddwl.goods.service.retail;

import cn.hutool.core.util.StrUtil;
import com.ddwl.common.constant.BaseEnum;
import com.ddwl.common.constant.Constant;
import com.ddwl.common.constant.GoodsEnum;
import com.ddwl.common.exception.ParamException;
import com.ddwl.common.util.BeanConverUtils;
import com.ddwl.common.util.UUIDGenerator;
import com.ddwl.goods.dao.CategoryDao;
import com.ddwl.goods.dao.ItemDao;
import com.ddwl.goods.model.Category;
import com.ddwl.goods.model.Item;
import com.ddwl.schema.bo.goods.ShopItemDefaultCategoryBo;
import com.ddwl.schema.bo.goods.retail.*;
import com.ddwl.schema.vo.goods.retail.ShopItemCategoryListVo;
import com.ddwl.schema.vo.goods.retail.ShopItemCategoryPageVo;
import com.ddwl.schema.vo.goods.retail.ShopItemCategoryVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author hemiaojun
 * @Date 2020/11/30 17:13
 */
@Service
@RequiredArgsConstructor
public class ShopItemCategoryService {

    private final CategoryDao categoryDao;
    private final ItemDao itemDao;


    /**
     * 店铺新建商品分类
     *
     * @param bo
     * @param shopId
     */
    public void addShopItemCategory(ShopItemCategoryBo bo, String shopId) {
        Category category = BeanConverUtils.convertBean(bo, Category.class);
        category.setShopId(shopId);
        addCategory(category);
    }

    private ShopItemCategoryVo addCategory(Category category) {
        checkDuplicateName(category.getShopId(), category.getName(), null);
        String code = getParentCode(category.getPid());
        category.setId(UUIDGenerator.getShortUUID());
        category.setCategoryCode(code + category.getId());
        category.setCategoryType(GoodsEnum.CategoryTypeEnum.RETAIL.getCode());
        category.setEffect(BaseEnum.StatusEnum.ENABLE.getCode());
        categoryDao.insert(category);
        return BeanConverUtils.convertBean(category, ShopItemCategoryVo.class);
    }

    private void checkDuplicateName(String shopId, String name, String id) {
        List<Category> categoryList = categoryDao.getDuplicateName(shopId, name, id);
        ParamException.isTrue(!CollectionUtils.isEmpty(categoryList), "店铺已经存在[" + name + "]分类");
    }

    /**
     * 修改
     *
     * @param bo
     */
    public void updateShopItemCategory(ShopItemCategoryUpdateBo bo, String shopId) {
        checkDuplicateName(shopId, bo.getName(), bo.getId());
        ParamException.isTrue((StrUtil.isNotEmpty(bo.getPid()) && bo.getPid().equals(bo.getId())), "父节点不能选择自己");
        String code = getParentCode(bo.getPid());
        Category category = BeanConverUtils.convertBean(bo, Category.class);
        category.setCategoryCode(code + category.getId());
        categoryDao.updateByPrimaryKeySelective(category);
        itemDao.updateCategoryCode(category.getId(), category.getCategoryCode());
    }

    private String getParentCode(String pid) {
        String code = "";
        if (StrUtil.isNotEmpty(pid)) {
            Category parent = categoryDao.selectByPrimaryKey(pid);
            ParamException.isTrue((null != parent && StrUtil.isNotEmpty(parent.getPid())), "分类最多支持二级");
            code = parent.getCategoryCode() + "/";
        }
        return code;
    }

    /**
     * 详情
     *
     * @param id
     * @return
     */
    public ShopItemCategoryVo getShopItemCategory(String id) {
        Category category = categoryDao.selectByPrimaryKey(id);
        return BeanConverUtils.convertBean(category, ShopItemCategoryVo.class);
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    public void deleteShopItemCategory(String id) {
        List<Category> categories = categoryDao.getSubListByPid(id);
        ParamException.isTrue((!CollectionUtils.isEmpty(categories)), "该分类下有子分类，不能删除！");
        List<Item> list = itemDao.getListByCategoryId(id);
        ParamException.isTrue((!CollectionUtils.isEmpty(list)), "该分类下的商品需要转移后才可以删除哦！");
        categoryDao.deleteById(id);
    }

    /**
     * 启用禁用
     *
     * @param bo
     */
    public void effect(ShopItemCategoryEffectBo bo) {
        Category category = BeanConverUtils.convertBean(bo, Category.class);
        List<Category> categories = categoryDao.getSubListByPid(category.getId());
        List<String> categoryIdList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(categories)) {
            categoryIdList = categories.stream().map(Category::getId).collect(Collectors.toList());
        }
        if (BaseEnum.StatusEnum.DISABLE.getCode().equals(bo.getEffect())) {
            categoryIdList.add(bo.getId());
            itemDao.offShelfItemByCategoryIdList(categoryIdList);
            categoryDao.updateEffectByIds(BaseEnum.StatusEnum.DISABLE.getCode(), categoryIdList);
        } else {
            categoryDao.updateByPrimaryKeySelective(category);
        }
    }

    /**
     * 排序
     *
     * @param bo
     */
    public void sort(ShopItemCategorySortBo bo) {
        Category category = BeanConverUtils.convertBean(bo, Category.class);
        categoryDao.updateByPrimaryKeySelective(category);
    }

    /**
     * 树结构列表
     *
     * @param bo
     * @return
     */
    public List<ShopItemCategoryPageVo> tree(ShopItemCategorySearchBo bo, String shopId) {
        Category category = BeanConverUtils.convertBean(bo, Category.class);
        category.setShopId(shopId);
        return categoryDao.treeShopItemCateGory(category);
    }

    public List<ShopItemCategoryListVo> list(String shopId) {
        List<Category> list = categoryDao.listShopItemCateGory(shopId);
        return fillCategoryTree(list);
    }

    public void addDefaultCategory(ShopItemDefaultCategoryBo bo) {
        Category category = BeanConverUtils.convertBean(bo, Category.class);
        if (StrUtil.isEmpty(category.getName())) {
            category.setName("其它");
        }
        category.setSort(99);
        addCategory(category);
    }

    public List<ShopItemCategoryVo> all(String shopId) {
        Category category = new Category();
        category.setShopId(shopId);
        return BeanConverUtils.convertBeanList(categoryDao.select(category), ShopItemCategoryVo.class);
    }

    public ShopItemCategoryVo addForMerchant(MerchantShopItemCategoryBo bo) {
        Category category = BeanConverUtils.convertBean(bo, Category.class);
        category.setSort(0);
        return addCategory(category);
    }

    public void rename(ShopItemCategoryRenameBo bo) {
        Category exist = categoryDao.selectByPrimaryKey(bo.getId());
        ParamException.isNull(exist, "商品分类信息异常");
        checkDuplicateName(exist.getShopId(), bo.getName(), bo.getId());
        Category category = BeanConverUtils.convertBean(bo, Category.class);
        categoryDao.updateByPrimaryKeySelective(category);
    }

    public List<ShopItemCategoryListVo> listForMerchant(String shopId) {
        List<Category> list = categoryDao.topListForMerchant(shopId);
        return BeanConverUtils.convertBeanList(list, ShopItemCategoryListVo.class);
    }

    public List<ShopItemCategoryListVo> selectList(String shopId) {
        List<Category> list = categoryDao.selectList(shopId);
        return fillCategoryTree(list);
    }

    private List<ShopItemCategoryListVo> fillCategoryTree(List<Category> list) {
        List<ShopItemCategoryListVo> voList = new ArrayList<>();
        for (Category category : list) {
            if (StrUtil.isEmpty(category.getPid())) {
                ShopItemCategoryListVo sic = BeanConverUtils.convertBean(category, ShopItemCategoryListVo.class);
                voList.add(sic);
                getItemCategoryTree(list, sic);
            }
        }
        return voList;
    }

    private ShopItemCategoryListVo getItemCategoryTree(List<Category> categories, ShopItemCategoryListVo shopItemCategoryListVo) {
        List<ShopItemCategoryListVo> fCategory = new ArrayList<>();
        for (Category category : categories) {
            if (shopItemCategoryListVo.getId().equals(category.getPid())) {
                ShopItemCategoryListVo siclv = BeanConverUtils.convertBean(category, ShopItemCategoryListVo.class);
                fCategory.add(siclv);
                getItemCategoryTree(categories, siclv);
            }
        }
        if (CollectionUtils.isEmpty(fCategory)) {
            return shopItemCategoryListVo;
        }
        shopItemCategoryListVo.setChildren(fCategory);
        return shopItemCategoryListVo;
    }

    public void sortForMerchant(List<String> ids) {
        if (!CollectionUtils.isEmpty(ids)) {
            for (int i = 0; i < ids.size(); i++) {
                Category category = new Category();
                category.setId(ids.get(i));
                category.setSort(i);
                categoryDao.updateByPrimaryKeySelective(category);
            }
        }
    }

}
